package cn.com.util;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;
import org.springframework.web.multipart.MultipartFile;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;

import cn.com.common.constants.Constants;
import cn.com.gas.constants.GasConstants;
import cn.com.gt3.entity.DmGySwjgEntity;
import cn.com.gt3.service.DmGySwjgService;
import cn.com.system.service.impl.HttpSessionService;
import lombok.extern.slf4j.Slf4j;

@Component
@Slf4j
public class TsBqUtils extends StringUtils {

	private static HttpSessionService httpSessionService;

	@Autowired
	public void setHttpSessionService(HttpSessionService httpSessionService) {
		TsBqUtils.httpSessionService = httpSessionService;
	}

	private static DmGySwjgService dmGySwjgService;

	@Autowired
	public void setDmGySwjgService(DmGySwjgService dmGySwjgService) {
		TsBqUtils.dmGySwjgService = dmGySwjgService;
	}

	/**
	 * 删除list0 里面 list1
	 * 
	 * @param list0
	 * @param list1
	 * @return
	 */
	public static List<String> listRemoveList(List<String> list0, List<String> list1) {
		List<String> list = new ArrayList<>();
		if (isNull(list1)) {
			return list0;
		}
		for (String string0 : list0) {
			for (String string1 : list1) {
				if (!string0.equals(string1)) {
					list.add(string0);
				}
			}
		}

		return list;
	}

	/**
	 * 获取文件后缀名
	 *
	 * @param fileName
	 *            文件名
	 * @return 后缀名
	 */
	public static String getFileType(String fileName) {
		if (fileName != null && fileName.contains(".")) {
			return fileName.substring(fileName.lastIndexOf("."));
		}
		return "";
	}

	/**
	 * 图片转base64字符串
	 *
	 * @param file
	 *            图片路径
	 * @return
	 */
	@SuppressWarnings("restriction")
	public static String imageToBase64Str(MultipartFile file) {

		InputStream inputStream = null;
		byte[] data = null;
		try {
			inputStream = file.getInputStream();
			data = new byte[inputStream.available()];
			inputStream.read(data);
			inputStream.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

		// 加密
		sun.misc.BASE64Encoder encoder = new sun.misc.BASE64Encoder();
		return encoder.encode(data);
	}

	/**
	 * object 转List
	 * 
	 * @param obj
	 * @param clazz
	 * @return
	 */
	public static <T> List<T> castList(Object obj, Class<T> clazz) {
		List<T> result = new ArrayList<T>();
		if (obj instanceof List<?>) {
			for (Object o : (List<?>) obj) {
				result.add(clazz.cast(o));
			}
			return result;
		}
		return null;
	}

	/**
	 * 获取uuid
	 * 
	 * @return
	 */
	public static String getUUID() {
		return UUID.randomUUID().toString().replaceAll("-", "");
	}

	@SuppressWarnings({ "rawtypes" })
	public static boolean isNull(Object obj) {
		boolean isNullFlag = true;
		if (obj != null) {
			if (obj instanceof List<?>) {
				isNullFlag = isNull((List<?>) obj);
			} else if (obj instanceof Set<?>) {
				isNullFlag = isNull((Set<?>) obj);
			} else if (obj instanceof Object[]) {
				isNullFlag = isNull((Object[]) obj);
			} else if (obj instanceof Map) {
				isNullFlag = isNull((Map) obj);
			} else if (obj instanceof String) {
				isNullFlag = isNull((String) obj);
			} else {
				isNullFlag = false;
			}
		}
		return isNullFlag;
	}

	/**
	 * 判断是否为空
	 *
	 * @param obj
	 *            输入
	 * @return 结果
	 * @author 作者 LIWEI
	 */
	public static boolean isNotNull(Object obj) {
		return !isNull(obj);
	}

	/**
	 * 判断列表是否为空
	 *
	 * @param list
	 *            传入一个列表
	 * @return boolean是否为空
	 */
	public static boolean isNull(List<?> list) {
		return list == null || list.size() == 0;
	}

	/**
	 * 判断列表是否为空
	 *
	 * @param set
	 *            set集合
	 * @return boolean值
	 */
	public static boolean isNull(Set<?> set) {
		return set == null || set.size() == 0;
	}

	/**
	 * 判断数组是否为空
	 *
	 * @param objects
	 *            任何对象
	 * @return boolean值
	 */
	public static boolean isNull(Object[] objects) {
		return objects == null || objects.length == 0;
	}

	/**
	 * 判断Map是否为空
	 *
	 * @param map
	 *            map集合
	 * @return boolean值
	 */
	public static boolean isNull(Map<?, ?> map) {
		return map == null || map.isEmpty();
	}

	/**
	 * 判断字符串是否为空
	 *
	 * @param str
	 *            字符串
	 * @return boolean值
	 */
	public static boolean isNull(String str) {
		return str == null || "".equals(str.trim()) || "null".equalsIgnoreCase(str.trim());
	}

	/**
	 * 获取数组长度
	 *
	 * @param list
	 *            列表
	 * @return int 数值
	 */
	public static int length(Collection<?> list) {
		return list == null ? 0 : list.size();
	}

	/**
	 * 获取数组长度
	 *
	 * @param list
	 *            列表
	 * @return int 数值
	 */
	public static int length(List<?> list) {
		return list == null ? 0 : list.size();
	}

	/**
	 * 获取数组长度
	 *
	 * @param objs
	 *            object对象
	 * @return int 数值
	 */
	public static int length(Object[] objs) {
		return objs == null ? 0 : objs.length;
	}

	/**
	 * 获取Map的长度
	 *
	 * @param map
	 *            集合
	 * @return int 数值
	 */
	public static int length(@SuppressWarnings("rawtypes") Map map) {
		return map == null ? 0 : map.size();
	}

	/**
	 * 获取字符串长度
	 *
	 * @param str
	 *            字符串
	 * @return int 数值
	 */
	public static int length(String str) {
		return str == null ? 0 : str.length();
	}

	/**
	 * 随机生成由数字、字母组成的N位验证码
	 *
	 * @return 返回一个字符串
	 */
	public static String getCode(int n) {
		char arr[] = new char[n];
		int i = 0;
		while (i < n) {
			char ch = (char) (int) (Math.random() * 124);
			if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z' || ch >= '0' && ch <= '9') {
				arr[i++] = ch;
			}
		}
		// 将数组转为字符串
		return new String(arr);
	}

	/**
	 * 两个Int相除
	 * 
	 * @param n1
	 * @param n2
	 * @return
	 */
	public static String divideInt(int n1, int n2) {
		// 创建一个数值格式化对象
		NumberFormat numberFormat = NumberFormat.getInstance();
		// 设置精确到小数点后2位
		numberFormat.setMaximumFractionDigits(2);
		if (n1 == 0 && n2 == 0) {
			return "0%";
		} else if (n2 == 0) {
			return "100%";
		} else if (n1 == 0) {
			return "0%";
		}

		String result = numberFormat.format((float) n1 / (float) n2 * 100);
		return result + "%";
	}

	/**
	 * 判断当前税务 省局、市局、县区局
	 * 
	 * @param swjg
	 * @return
	 */
	public static String getTaxOrgLevel(String swjg) {
		// 11305020000
		if ("00000000".equals(swjg.substring(3, 11))) {
			return Constants.TAX_PROVINCES;
		}
		;

		// 后面 6个0市局
		if ("000000".equals(swjg.substring(5, 11))) {
			return Constants.TAX_CITIES;
		}
		;

		// 后面 4个0县区局
		if ("0000".equals(swjg.substring(7, 11))) {
			return Constants.TAX_COUNTES;
		}
		;

		return swjg;
	}

	/**
	 * 判断List<String> 集合中是否存在重复
	 * 
	 * 集合中有重复元素 true 集合中没有重复元素 false
	 * 
	 * @param swjg
	 * @return
	 */
	public static boolean isListStringrepeat(List<String> list) {

		Set<String> set = new HashSet<>(list); // 将list转换为set去重
		if (list.size() == set.size()) {
			return false;
		} else {
			return true;
		}

	}

	/**
	 * 
	 * @param taxOrg
	 * @return
	 */
	public static List<DmGySwjgEntity> recursionLevelTaxOrg(String taxOrg) {
		TsBqUtils utils = new TsBqUtils();
		// String currentDeptId = httpSessionService.getCurrentDeptId();
		List<DmGySwjgEntity> dmGySwjgList = utils.recursionTaxOrg(taxOrg, new ArrayList<>());
		return dmGySwjgList;
	}

	public List<DmGySwjgEntity> recursionTaxOrg(String taxOrg, List<DmGySwjgEntity> list) {
		LambdaQueryWrapper<DmGySwjgEntity> lambdaQuery = Wrappers.lambdaQuery();

		List<DmGySwjgEntity> swjgEntityList = dmGySwjgService
				.list(lambdaQuery.eq(DmGySwjgEntity::getSjswjgDm, taxOrg).eq(DmGySwjgEntity::getYxbz, "Y"));
		if (TsBqUtils.isNull(swjgEntityList)) {
			return list;
		} else {

			for (DmGySwjgEntity dmGySwjgEntity : swjgEntityList) {
				list.add(dmGySwjgEntity);
			}

			for (DmGySwjgEntity dmGySwjgEntity : swjgEntityList) {
				String swjgDm = dmGySwjgEntity.getSwjgDm();
				recursionTaxOrg(swjgDm, list);
			}
		}

		return list;
	}

	/**
	 * 将Base64位编码的图片进行解码，并保存到指定目录
	 * 
	 * @param base64
	 * @param path
	 * @param imgName
	 */
	@SuppressWarnings("restriction")
	public static boolean decodeBase64ToImage(String base64, String path, String imgName) {
		String base = base64.substring(base64.indexOf(",") + 1);
		if (base == null)
			return false;
		sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
		try {
			// 解密
			byte[] b = decoder.decodeBuffer(base);
			// 处理数据
			for (int i = 0; i < b.length; ++i) {
				if (b[i] < 0) {// 调整异常数据
					b[i] += 256;
				}
			}
			// 文件夹不存在则自动创建
			File tempFile = new File(path + imgName);
			if (!tempFile.getParentFile().exists()) {
				tempFile.getParentFile().mkdirs();
			}
			java.io.OutputStream out = new java.io.FileOutputStream(tempFile);

			out.write(b);
			out.flush();
			out.close();
			return true;
		} catch (Exception e) {
			return false;
		}

	}
	
	public static String getFilenameExtension(String filename) {
		int dotIndex = filename.lastIndexOf(".");
		if (dotIndex > 0) {
		    String extension = filename.substring(dotIndex + 1);
		    return extension;
		}else{
			return "";
		}
		
	}
	
	/**
	 * 
	 * 获取 base64 的后缀
	 * 
	 * @param base64String
	 * @return
	 */
	public static String getBase64Extension(String base64String) {
		// 检查base64String是否为空
		if (base64String == null || base64String.isEmpty()) {
			return "";
		}

		// 分割base64字符串，获取后缀
		String[] parts = base64String.split(",");
		if (parts.length > 1) {
			// data:image/jpeg;base64
			return parts[0].split(";")[0].split("/")[1];
		}

		// 如果没有MIME类型，则返回空字符串
		return "";
	}

	/**
	 * 计算日期之间的天数差
	 * 
	 * @param dateStr1
	 * @param dateStr2
	 * @return
	 */
	public static Long calcMergeDays(String dateStr1, String dateStr2) {
		// 定义日期格式
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
		// 解析日期字符串为LocalDate对象
		LocalDate date1 = LocalDate.parse(dateStr1, formatter);
		LocalDate date2 = LocalDate.parse(dateStr2, formatter);
		// 计算日期之间的天数差
		long daysBetween = ChronoUnit.DAYS.between(date1, date2);
		return daysBetween;
	}

	/**
	 * 四舍五入
	 * 
	 * @param str
	 * @return
	 */
	public static String roundItUp(String str) {
		BigDecimal bd = new BigDecimal(str).setScale(2, RoundingMode.HALF_UP);
		return bd.toString();
	}

	public static boolean isDate(String date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		sdf.setLenient(false); // 设置严格模式，不允许解析不严格对应格式的日期
		try {
			sdf.parse(date);
			return true;
		} catch (ParseException e) {
			return false;
		}
	}

	public static boolean dateSubtract(String date1, String date2, long l) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		sdf.setLenient(false); // 设置严格模式，不允许解析不严格对应格式的日期

		try {
			long _l = (sdf.parse(date1).getTime() - sdf.parse(date2).getTime()) / 1000l;
			if (_l > l) {
				return true;
			} else {
				return false;
			}
		} catch (ParseException e) {
			return false;
		}
	}
	
	public static long dateSubtract(String date1, String date2) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
		sdf.setLenient(false); // 设置严格模式，不允许解析不严格对应格式的日期

		try {
			long _l = (sdf.parse(date1).getTime() - sdf.parse(date2).getTime()) / 1000l;
			return _l;
		} catch (ParseException e) {
			return 0l;
		}
	}
	
	/**
	 * 判断在线或者离线
	 * 
	 * @param str
	 * @return
	 */
	public static String isOnline(String name,String online) {
		int index = name.lastIndexOf("(");
		if (index != -1) {
			String substring = name.substring(index);
			if(TsBqUtils.isNotNull(substring)){
				String[] split = substring.split("/");
				String string = split[0];
				String replace = string.replace("(", "");
			    int number = Integer.parseInt(replace);
			    return (number > 0) ? GasConstants.ON_LINE : GasConstants.OFF_LINE;
			}
		}
		
		return online;
	}
	
	
	/**
	 * 处理 字符串中最后一个(后面的字符
	 * 
	 * @param str
	 * @return
	 */
	public static String handleEndBeforeParentheses(String str) {
		int index = str.lastIndexOf("(");

		if (index != -1) {
			return str.substring(0, index);
		}
		return str;
	}

	public static boolean isConvertibleToInt(String str) {
		try {
			Integer.parseInt(str);
			return true;
		} catch (NumberFormatException e) {
			return false;
		}
	}
	
	public static void zipFile(File inputFile, ZipOutputStream ouputStream,String name) {
		try {
			if (inputFile.exists()) {
				if (inputFile.isFile()) {
					
					// 待压缩文件输入流
					FileInputStream IN = new FileInputStream(inputFile);
					// 创建 BufferedInputStream具有指定缓冲区大小，并保存其参数，输入流 in ，供以后使用。
					BufferedInputStream bins = new BufferedInputStream(IN, 512);
					// ZipEnter:表示压缩文件的条目(文件目录)
					// ZipEntry entry = new ZipEntry(name); // 重命名文件
					
					ZipEntry entry = new ZipEntry(name); // 重命名文件
					// 在zip流中创建一个entry文件
					ouputStream.putNextEntry(entry);
					
					int nNumber;
                    byte[] buffer = new byte[512];
                    while ((nNumber = bins.read(buffer)) != -1) {
                        ouputStream.write(buffer, 0, nNumber);
                    }

                    StreamUtils.copy(IN, ouputStream);
					
					// 关闭流
					bins.close();
					IN.close();
					
				} else {
					// 处理文件夹的情况
					try {
						/*File[] files = inputFile.listFiles();
						for (int i = 0; i < files.length; i++) {
							zipFile(files[i], ouputStream);
						}*/
					} catch (Exception e) {
						e.printStackTrace();
						log.error(e.getMessage());
						
					}
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
		}
	}
}
